package com.example.administrator.activitydemo;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;
import android.widget.ImageView;
import android.widget.ListView;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;

public class ImageLoader {

    private ImageView mImageView;
    private String mUrl;

    //创建cache，理解上可以把lrucache当做map
    private LruCache<String,Bitmap> mCaches;
    private ListView mListView;
    private Set<NewsAsyncTask> mTask;

    public ImageLoader(ListView listview){
        mListView = listview;
        mTask = new HashSet<>();
        //获取最大可用内存
        int maxMemory = (int) Runtime.getRuntime().maxMemory();
        int cacheSize = maxMemory/4;
        mCaches = new LruCache<String,Bitmap>(cacheSize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                //在每次存入缓存的时候调用，将bitmap大小存入进去
                return value.getByteCount();
            }
        };
    }


    //增加到缓存
    public void addBitmapToCache(String url,Bitmap bitmap){
        if(getBitmapFromCache(url)==null){
            mCaches.put(url,bitmap);
        }
    }

    //从缓存中获取数据-----我们只需要将lruCache当成map就可以了
    public Bitmap getBitmapFromCache(String url){
        return mCaches.get(url);
    }



    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if(mImageView.getTag().equals(mUrl)){
                mImageView.setImageBitmap((Bitmap) msg.obj);
            }
        }
    };

    //不能直接把bitmap设置给imageview(由于安卓的单线程模式)，所以只能通过Handler
    //如果使用AsyncTask，就不用这个方法了
    public void showImageByThread(ImageView imageView, final String url){
        mImageView = imageView;
        mUrl = url;

        new Thread(){
            @Override
            public void run() {
                super.run();
                Bitmap bitmap = getBitmapFromURL(url);
                Message message = Message.obtain();//这样不new能提高message使用效率
                message.obj = bitmap;
                mHandler.sendMessage(message);
            }
        }.start();
    }

    /**
     * 将urlString 转换成了一个bitmap
     * @param urlString
     * @return
     */
    public Bitmap getBitmapFromURL(String urlString){
        Bitmap bitmap;
        InputStream is = null;
        try {
            URL url = new URL(urlString);
            HttpURLConnection connection= (HttpURLConnection) url.openConnection();
            is = new BufferedInputStream(connection.getInputStream());
            bitmap = BitmapFactory.decodeStream(is);//解析为我们需要的bitmap
            connection.disconnect();//将资源释放
            //Thread.sleep(1000);//试试网络慢的情况
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    //将由loadImage()方法代替showImageByAsyncTask()方法
    public void showImageByAsyncTask(ImageView imageView,String url){
        //从缓存中取出对应的图片
        Bitmap bitmap = getBitmapFromCache(url);
        if(bitmap ==null) {
            //new NewsAsyncTask( url).execute(url);//没有缓存则从网络下载
            imageView.setImageResource(R.mipmap.ic_launcher);
        }else {
            imageView.setImageBitmap(bitmap);//有缓存则直接从内存中拿出，依然在主线程，可以直接设置
        }
    }

    public void cancelAllTasks(){
        if(mTask!=null){
            for (NewsAsyncTask task : mTask) {
                task.cancel(false);
            }
        }
    }

    //用来加载从start到end的所有图片
    public void loadImages(int start,int end){
        for (int i = start; i <end ; i++) {
            String url = NewsAdapter.URLS[i];
            //从缓存中取出对应的图片
            Bitmap bitmap = getBitmapFromCache(url);
            if(bitmap ==null) {
                NewsAsyncTask task = new NewsAsyncTask(url);
                task.execute(url);
                mTask.add(task);//将新创建的task存到task集合里面
            }else {
                ImageView imageView = (ImageView) mListView.findViewWithTag(url);
                imageView.setImageBitmap(bitmap);//有缓存则直接从内存中拿出，依然在主线程，可以直接设置
            }
        }
    }

    private class NewsAsyncTask extends AsyncTask<String,Void,Bitmap>{

        private ImageView mImageView;
        private String mUrl;

        public NewsAsyncTask(String url) {
            //mImageView = imageView;
            mUrl = url;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            String url = params[0];
            //从网络获取图片
            Bitmap bitmap = getBitmapFromURL(url);
            if(bitmap!=null){
                //将不再缓存的图片加入缓存
                addBitmapToCache(url,bitmap);//将url对应的bitmap保存到cache中
            }
            return bitmap;

        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            /*if(mImageView.getTag().equals(mUrl)) {//相当于设置了身份验证
                mImageView.setImageBitmap(bitmap);
            }*/
            ImageView imageView = (ImageView) mListView.findViewWithTag(mUrl);
            if(imageView!=null && bitmap!=null){
                imageView.setImageBitmap(bitmap);
            }
        }
    }
}
